#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 打开与 X 服务器的连接
    Display *display = XOpenDisplay(NULL);
    if (!display) {
        fprintf(stderr, "无法打开 X 显示\n");
        return 1;
    }

    int screen = DefaultScreen(display);
    Window root = RootWindow(display, screen);

    // 获取默认颜色
    unsigned long black = BlackPixel(display, screen);
    unsigned long white = WhitePixel(display, screen);

    // 创建窗口
    Window window = XCreateWindow(
        display, root, 100, 100, 400, 300, 0,
        CopyFromParent, InputOutput, CopyFromParent,
        0, NULL  // 初始属性为空
    );

    // 设置窗口标题
    XStoreName(display, window, "XChangeWindowAttributes 示例");

    // 映射窗口（显示）
    XMapWindow(display, window); // not work ?
    XSync(display, False);

    // 初始属性：背景为黑色，边框为白色，监听 Expose 和 KeyPress 事件
    XSetWindowAttributes attrs;
    attrs.background_pixel = black;
    attrs.border_pixel = white;
    attrs.event_mask = ExposureMask | KeyPressMask;

    // 设置窗口属性（初始）
    XChangeWindowAttributes(display, window, 
                            CWBackPixel | CWBorderPixel | CWEventMask, 
                            &attrs);

#if 1
    // 修改属性：背景为红色，边框为绿色，监听鼠标点击事件
    attrs.background_pixel = 0xFF0000;  // 红色
    attrs.border_pixel = 0x00FF00;      // 绿色
    attrs.event_mask = ButtonPressMask; // 监听鼠标点击
    attrs.override_redirect = True;
    attrs.do_not_propagate_mask = /*ButtonPressMask | ButtonReleaseMask | */ FocusChangeMask;
    // 更新窗口属性
    XChangeWindowAttributes(display, window, 
                            CWBackPixel | CWBorderPixel | CWEventMask |  /* CWDontPropagate | */ CWOverrideRedirect , 
                            &attrs);

    // 刷新窗口背景
    XClearWindow(display, window);

    // 映射窗口（显示）
    XMapWindow(display, window);

    XSync(display, False);

    XSelectInput(display, window, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | FocusChangeMask | PropertyChangeMask | ExposureMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask);
    XSync(display, False);
#endif


    // 事件循环
    XEvent event;
    while (1) {
        XNextEvent(display, &event);

        // 处理键盘事件
        if (event.type == KeyPress) {
            printf("键盘按键被按下，退出程序\n");
            break;
        }

        // 处理鼠标点击事件
        if (event.type == ButtonPress) {
            printf("鼠标点击: 按钮 %d\n", event.xbutton.button);
        }

        // 处理暴露事件（窗口首次显示或被覆盖后）
        if (event.type == Expose) {
            printf("窗口暴露事件\n");
        }
    }

    // 关闭连接
    XCloseDisplay(display);
    return 0;
}
